import 'package:flutter/material.dart';
import 'package:super_tool_server/page/page_route.dart';

class CustomRouteParser extends RouteInformationParser<List<RouteSettings>> {
  @override
  Future<List<RouteSettings>> parseRouteInformation(
      RouteInformation routeInformation) {
    final uri = Uri.parse(routeInformation.location!);

    if (uri.pathSegments.isEmpty) {
      return Future.value([const RouteSettings(name: '/')]);
    }

    final routeSettings = uri.pathSegments
        .map((pathSegment) => RouteSettings(
              name: '/$pathSegment',
              arguments: pathSegment == uri.pathSegments.last
                  ? uri.queryParameters
                  : null,
            ))
        .toList();

    return Future.value(routeSettings);
  }

  @override
  RouteInformation restoreRouteInformation(List<RouteSettings> configuration) {
    String? location = configuration.last.name;
    Map<String, dynamic> argumentsPre = {};
    if (configuration.last.arguments != null) {
      argumentsPre = configuration.last.arguments! as Map<String, dynamic>;
    }
    // if (configuration.last.name == PageManager.page_home) {
    //   if (argumentsPre[GlobalConstant.innerPage] != null) {
    //     location = argumentsPre[GlobalConstant.innerPage]!.toString();
    //   }
    // }
    final arguments = _restoreArguments(configuration.last);

    return RouteInformation(location: '$location$arguments');
  }

  String _restoreArguments(RouteSettings routeSettings) {
    Map<String, dynamic> arguments = {};
    if (routeSettings.arguments != null) {
      arguments = routeSettings.arguments! as Map<String, dynamic>;
    }
    // if (routeSettings.name == PageManager.page_userDetail) {
    //   return '?cardId=${arguments["cardId"].toString()}';
    // }
    // if (routeSettings.name == PageManager.page_createContent) {
    //   return '?cardId=${arguments["cardId"].toString()}&ownership=${arguments["ownership"].toString()}';
    // }
    // if (routeSettings.name == PageManager.page_myContents) {
    //   return '?cardId=${arguments["cardId"].toString()}&ugcId=${arguments["ugcId"].toString()}';
    // }
    return '';
  }
}

class CustomRouteDelegate extends RouterDelegate<List<RouteSettings>>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<List<RouteSettings>> {
  final _pages = <Page>[];
  final _popUpBox = <String, Widget>{}; //弹出框
  final _popUpCount = <String, int>{}; //弹出框引用计数

  @override
  final navigatorKey = GlobalKey<NavigatorState>();

  @override
  List<Page> get currentConfiguration => List.of(_pages);

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: List.of(_pages),
      onPopPage: _onPopPage,
      // transitionDelegate: const MyTransitionDelegate(),
    );
  }

  @override
  Future<bool> popRoute() {
    if (_pages.length > 1) {
      _pages.removeLast();
      notifyListeners();
      return Future.value(true);
    }

    // return _confirmAppExit();
    return Future.value(false);
  }

  @override
  Future<void> setNewRoutePath(List<RouteSettings> configuration) {
    _setPath(configuration
        .map((routeSettings) => _createPage(routeSettings))
        .toList());
    return Future.value(null);
  }

  bool _onPopPage(Route route, dynamic result) {
    if (!route.didPop(result)) return false;

    popRoute();
    return true;
  }

  String? topPageName() {
    if (_pages.isNotEmpty) {
      var topPage = _pages[_pages.length - 1];
      // if (topPage is NoAnimationPage) {
      //   NoAnimationPage noAmimationPage = topPage as NoAnimationPage;
      //   Map<String, dynamic> arguments = noAmimationPage.arguments as Map<String, dynamic>;
      //   return arguments['innerPage'].toString();
      // }
      return topPage.name;
    }
    return '';
  }

  dynamic getNavigatorKey() {
    return navigatorKey;
  }

  bool containPage(String pageName) {
    bool contain = false;
    for (var page in _pages) {
      if (page is NoAnimationPage) {
        NoAnimationPage noAmimationPage = page as NoAnimationPage;
        Map<String, dynamic> arguments =
            noAmimationPage.arguments as Map<String, dynamic>;
        if (arguments['innerPage'].toString() == pageName) {
          contain = true;
          break;
        }
      } else {
        if (page.name == pageName) {
          contain = true;
          break;
        }
      }
    }
    return contain;
  }

  void _setPath(List<Page> pages) {
    _pages.clear();
    _pages.addAll(pages);

    if (pages.isNotEmpty && _pages.first.name != '/') {
      _pages.insert(0, _createPage(const RouteSettings(name: '/')));
    }
    notifyListeners();
  }

  void pushPage(
      {required String name, Map<String, dynamic> arguments = const {}}) {
    _pages.add(_createPage(RouteSettings(name: name, arguments: arguments)));
    notifyListeners();
  }

  void pushPopUpBox({required String key, required Widget boxWidget}) {
    // 对key去重
    if (!_popUpBox.containsKey(key)) {
      _popUpBox[key] = boxWidget;
      _popUpCount[key] = 1;
    } else {
      _popUpCount[key] = _popUpCount[key]! + 1;
    }
    List<Page> pages = List.from(_pages);
    _setPath(pages);
  }

  Map<String, Widget> getPopUpBox({required String key}) {
    return _popUpBox;
  }

  Future<bool> popPopUpBox({required String key}) {
    if (_popUpBox.isNotEmpty && _popUpBox.containsKey(key)) {
      _popUpCount[key] = _popUpCount[key]! - 1;
      if (_popUpCount[key] == 0) {
        _popUpBox.remove(key);
        _popUpCount.remove(key);
      }
      List<Page> pages = List.from(_pages);
      _setPath(pages);
      return Future.value(true);
    }
    return Future.value(false);
  }

  void pushAndReplace(
      {required String name, Map<String, dynamic> arguments = const {}}) {
    if (_pages.length > 1) {
      _pages.removeLast();
    }
    _pages.add(_createPage(RouteSettings(name: name, arguments: arguments)));
    notifyListeners();
  }

  // 强制回到首页
  void gotoHome(
      {required String homePageName,
      Map<String, dynamic> arguments = const {}}) {
    if (_pages.length > 1) {
      _pages.clear();
    }
    _pages.add(
        _createPage(RouteSettings(name: homePageName, arguments: arguments)));
    notifyListeners();
  }

  // 退栈到指定的路由
  void popUntil(String name) {
    int start = -1;
    start = _pages.lastIndexWhere((element) => element.name == name);
    if (start + 1 > 0 && start + 1 < _pages.length) {
      // 根路由不允许退出
      _pages.removeRange(start + 1, _pages.length);
    }
    notifyListeners();
  }

  bool canPop() {
    if (_pages.length > 1) {
      return true;
    }
    return false;
  }

  Page _createPage(RouteSettings routeSettings) {
    Map<String, dynamic> arguments = {};
    if (routeSettings.arguments != null) {
      arguments = routeSettings.arguments! as Map<String, dynamic>;
    }
    Widget child =
        PageManager.getPage(routeSettings.name, arguments: arguments);

    return NoAnimationPage(
      child: child,
      key: Key(routeSettings.toString()) as LocalKey,
      name: routeSettings.name,
      arguments: arguments,
    );
  }

  Future<bool> _confirmAppExit() async {
    final result = await showDialog<bool>(
        context: navigatorKey!.currentContext!,
        builder: (context) {
          return AlertDialog(
            title: const Text('Exit App'),
            content: const Text('Are you sure you want to exit the app?'),
            actions: [
              TextButton(
                child: const Text('Cancel'),
                onPressed: () => Navigator.pop(context, true),
              ),
              TextButton(
                child: const Text('Confirm'),
                onPressed: () => Navigator.pop(context, false),
              ),
            ],
          );
        });

    return result ?? true;
  }
}

// 无动画路由页面
class NoAnimationPage extends Page {
  const NoAnimationPage({
    required this.child,
    required LocalKey key,
    String? name,
    Object? arguments,
  }) : super(key: key, name: name, arguments: arguments);
  final Widget child;

  @override
  Route<dynamic> createRoute(BuildContext context) => PageRouteBuilder<dynamic>(
        settings: this,
        pageBuilder: (_, __, ___) => child,
      );
}
